memo = {}
def conteo(state, r):
    try:
        return memo[state]
    except KeyError:
        pass

    if not state:
        return 1
    if state[0]:
        total = 0
        for k in state[0]:
            st = [set(row) for row in state]
            for i in range(r):
                if i >= len(st):
                    break
                st[i].discard(k)
                st[i].discard(k-i)
                st[i].discard(k+i)
            newState = tuple(tuple(sorted(row)) for row in st[1:])
            total += conteo(newState, r)
        memo[state] = total
        return total
    else:
        return 0




if __name__ == "__main__":
    n = 14
    state = tuple([tuple(range(n)) for _ in range(n)])

    total = 0
    for r in range(1, n+1):
        memo.clear()
        val = conteo(state, r)
        total += val
        print val
    print("Solution: %s " % total)
